//===============================================================================
// Microsoft patterns & practices Enterprise Library Contribution
// Resource Application Block
//===============================================================================

using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Collections.Specialized;
using System.ComponentModel;
using System.Diagnostics;
using System.Drawing.Design;
using System.Windows.Forms;
using Microsoft.Practices.EnterpriseLibrary.Configuration.Design;
using Microsoft.Practices.EnterpriseLibrary.Configuration.Design.Validation;

namespace EntLibContrib.Resource.Configuration.Design
{
	/// <summary>
	/// Represents a custom reource provider that consists of key value pairs. 
	/// </summary>
	public class CustomResourceProviderNode : ResourceProviderNode
	{
		#region Fields
		private List<EditableKeyValue> editableAttributes = new List<EditableKeyValue>();
		private string typeName;
		internal string resourceBaseName;
		#endregion

		#region Properties
		/// <summary>
		/// Gets or sets the attributes for the custom resource provider.
		/// </summary>
		/// <value>
		/// The attributes for the custom resource provider.
		/// </value>		
		[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Design", "CA1002:DoNotExposeGenericLists")]
		[CustomAttributesValidation]
		[ResourceCategory("CategoryProvider")]
		[ResourceDescription("CustomResourceProviderExtensionsDescription")]
		public List<EditableKeyValue> Attributes
		{
			get
			{
				return editableAttributes;
			}
		}

		/// <summary>
		/// Gets or sets the <see cref="Type"/> that implements <see cref="IResourceProvider"/>.
		/// </summary>
		/// <value>
		/// The <see cref="Type"/> that implements <see cref="IResourceProvider"/>.
		/// </value>
		[Required]
		[Editor(typeof(TypeSelectorEditor), typeof(UITypeEditor))]
		[BaseType(typeof(IResourceProvider), typeof(CustomResourceProviderData))]
		[ResourceCategory("CategoryProvider")]
		[ResourceDescription("CustomResourceProviderNodeTypeDescription")]
		public string Type
		{
			get { return typeName; }
			set { typeName = value; }
		}

		/// <summary>
		/// Gets or sets the resource base name.
		/// </summary>
		/// <value>The resource base name.</value>
		[Required]
		[ResourceCategory("CategoryProvider")]
		[ResourceDescription("ResourceBaseNameDescription")]
		public string ResourceBaseName
		{
			get
			{
				return this.resourceBaseName;
			}
			set
			{
				if (value == null)
					this.resourceBaseName = String.Empty;
				else
					this.resourceBaseName = value.Trim();
			}
		}

		/// <summary>
		/// Gets a <see cref="CustomResourceProviderData"/> configuration object using the node data.
		/// </summary>
		/// <value>
		/// A <see cref="CustomResourceProviderData"/> configuration object using the node data.
		/// </value>
		[ReadOnly(true)]
		public override ResourceProviderData ResourceProviderData
		{
			get
			{
				CustomResourceProviderData customProviderData = new CustomResourceProviderData(Name, ResourceBaseName, typeName);
				foreach (EditableKeyValue keyValue in editableAttributes)
				{
					customProviderData.Attributes.Set(keyValue.Key, keyValue.Value);
				}
				return customProviderData;
			}
		}
		#endregion

		#region Construction
		/// <summary>
		/// Initialize a new instance of the <see cref="CustomResourceProviderNode"/> class.
		/// </summary>
		public CustomResourceProviderNode()
			: this(new CustomResourceProviderData(InternalResources.DefaultCustomResourceProviderNodeName, string.Empty, string.Empty))
		{
		}

		/// <summary>
		/// Initialize a new instance of the <see cref="CustomResourceProviderNode"/> class with a <see cref="CustomResourceProviderData"/> object.
		/// </summary>
		/// <param name="customResourceProviderData">The <see cref="CustomResourceProviderData"/> to display.</param>
		public CustomResourceProviderNode (CustomResourceProviderData customResourceProviderData)
		{
			if ( null == customResourceProviderData ) throw new ArgumentNullException("customResourceProviderData");

			Rename(customResourceProviderData.Name);
			NameValueCollection attributes = new NameValueCollection(customResourceProviderData.Attributes);
			attributes.Remove(ResourceProviderData.ResourceBaseNameProperty);
			foreach (string key in attributes)
			{
				editableAttributes.Add(new EditableKeyValue(key, attributes[key]));
			}
			this.typeName = customResourceProviderData.TypeName;
			this.resourceBaseName = customResourceProviderData.ResourceBaseName;
		}
		#endregion
	}
}